//
//  UserAccountViewModel.swift
//  微博01
//
//  Created by 牛威 on 15/12/8.
//  Copyright © 2015年 牛威. All rights reserved.
//

import Foundation


//用户账户视图模型  没有父类

 /*

  模型通常继承自NSObject,使用KVC-设置属性,简化对象构造

  如果没有父类,所有东西都要从头创建,量级轻

  视图模型的作用,封装业务逻辑,通常没有复杂的属性



 **/


class UserAccountViewModel {
    
    //创建一个有效的accessToken属性 -->在网络工具中进行字典处理-->修改网络方法 
    
    var accesstToken : String? {
    
        if !isExpired { //如果没有过期返回 token
        
            //要是account也没有值 也会返回nil
        
            return account?.access_token
        
        }
        
        return nil
    
    }
    
    
    
    //MARK: - 单例对象的创建 为了避免从沙盒中多次调用归档数据的麻烦 提高效率 让access容易被访问到
    
    static var sharedAccount = UserAccountViewModel()
    
    //用户模型

    var account : NWAccountModel?
    
    
    //用户登录标识的计算型属性
    
    
     var isLogin : Bool {
    
    
        //两个条件 token不能为空和没有过期同时满足说明登录成功
        
        return account?.access_token != nil && !isExpired
    
    
    }
    
    
    //计算性属性类似于有返回值的函数 归档路径 不使用函数的原因就是语义更清晰
    
   private var accountPath : String {
    
    let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask, true).last!
    
    return (path as NSString).stringByAppendingPathComponent("account.plist")
    
    }
    
//    //MARK: - 与计算型属性做对比
//    
//    private func accountP ()->String{
//    
//        let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask, true).last!
//        
//        return (path as NSString).stringByAppendingPathComponent("account.plist")
//       
//    }
    
    
    
    
    
    
    
    //MARK: - 判断账户是否过期的计算型属性
    
    private var isExpired : Bool {
        
        //测试逻辑 距离现在的上一个小时
        
//        account?.expiresDate = NSDate.timeIntervalSinceDate(-3600)
        
//        print(account?.expiresDate)
    
        //把当前获取的过期时间和             当前时间作比较 如果返回小于说明过期 大于说明没有过期
        
//     if  account?.expiresDate?.compare(NSDate()) == CFComparisonResult.CompareGreaterThan {
        
     // 没有过期
        
        return false

//    }
      
        //过期
        
//     return true
        
}
    
    
    //实例化 构造函数不需要重写 不需要重写也不需要继承
    //加一个 private 就只能要求从外部只能通过单例进行实例化而不会 ()这样被重复调用
    
  private  init(){
    
    
        //从沙盒解档 恢复当前数据 磁盘读写的速度最慢,没有内存读写的速度快 如何改写以下这个输出多次账户的问题-->单例
        
     account =  NSKeyedUnarchiver.unarchiveObjectWithFile(accountPath) as? NWAccountModel
        
        
        //如果过期了 清空解档数据
        
        if isExpired {
        
            
        print("已经过期")
        
        account = nil
        
        }
        
        //判断账户是否过期
        
//        print(account)
    
    }



}

//MARK: - 封装关于账户的一些网络处理

/*
   代码重构的步骤

     1 新方法
     2 粘贴代码
     3 根据上下文调整参数和返回值
     4 适当的移动一些子方法


**/

extension UserAccountViewModel {
    
    //增加一个闭包 告诉用户成功与否


    func loadAccessToken(code:String,finished : (isSuccessed:Bool)->()) {
    
    
        //MARK: - 根据code加载token
        
        NetTools.shared.loadAccessToken(code) { (result, error) -> () in
            
            if error != nil {
                
                print("加载出错了")
                
                //失败回调
                
                finished(isSuccessed: false)
                
                return
                
            }
            
            // 这里要需要强制类型转换 as !/? 类型
            
             self.account = NWAccountModel.init(dict: result as! [String : AnyObject])
            
            //加载用户信息
            
            self.userInfo(self.account!,finished: finished)
            
            
        }
    }
    
    
    func userInfo(accout : NWAccountModel,finished : (isSuccessed:Bool)->()){
        
        
        NetTools.shared.loadUserInfo(Uid:accout.uid!) { (result, error) -> () in
            
            //一定有内容的判断
            if error != nil {
                
                print("错误了")
                
                finished(isSuccessed: false)
                
                return
                
            }
            
            print(result)
            
            //一定是字典的判断
            
            guard let dict = result as?[String : AnyObject] else{
                
                print("格式有误")
                
                finished(isSuccessed: false)
                
                return
                
            }
            
            // 走到这一步的时候 dict一定有值了
            
            
            accout.screen_name = dict["screen_name"] as? String
            accout.avatar_large = dict["avatar_large"] as? String
                                    
            NSKeyedArchiver.archiveRootObject(self.account!, toFile: self.accountPath)
            
            //成功回调
            
            finished(isSuccessed: true)
            
        }
        
    }


}